package com.wxzz.elearing.evaluation.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.wxzz.elearing.evaluation.amqp.EvaluationProducer;
import com.wxzz.elearing.evaluation.dto.*;
import com.wxzz.elearing.evaluation.entity.*;
import com.wxzz.elearing.evaluation.mapper.*;
import com.wxzz.elearing.evaluation.service.IBusinessCategoryEvaluationService;
import com.wxzz.elearing.evaluation.service.openfeign.IEnterpriseApiFeign;
import com.wxzz.elearing.evaluation.service.openfeign.IEnterpriseOrganizationApiFeign;
import com.wxzz.elearing.evaluation.service.openfeign.IWxUserApiFeign;
import com.wxzz.elearning.common.dto.SystemMessageMqDto;
import com.wxzz.elearning.common.exception.ServiceException;
import com.wxzz.elearning.common.utils.OpenFeignUtil;
import com.wxzz.elearning.common.vo.JgPageVo;
import com.wxzz.elearning.common.vo.ReturnVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 能力测评 服务实现类
 * </p>
 *
 * @author
 * @since 2021-04-10
 */
@Service
public class BusinessCategoryEvaluationServiceImpl extends ServiceImpl<BusinessCategoryEvaluationMapper, BusinessCategoryEvaluation> implements IBusinessCategoryEvaluationService {

    @Autowired
    private BusinessCategoryEvaluationMapper businessCategoryEvaluationMapper;

    @Override
    public ReturnVO saveBusinessCategoryEvaluation(BusinessCategoryEvaluation businessCategoryEvaluation) {
        if (businessCategoryEvaluation.getId() == null) {
            businessCategoryEvaluationMapper.insert(businessCategoryEvaluation);
        } else {
            businessCategoryEvaluationMapper.updateById(businessCategoryEvaluation);
        }
        return new ReturnVO("能力测评添加成功", businessCategoryEvaluation.getId());
    }

    @Override
    public ReturnVO deleteBusinessCategoryEvaluationId(Long businessCategoryEvaluationId) {
        businessCategoryEvaluationMapper.deleteById(businessCategoryEvaluationId);
        return new ReturnVO("根据id删除能力测评", businessCategoryEvaluationId);
    }

    @Autowired
    private BusinessCategoryMapper businessCategoryMapper;

    @Override
    public ReturnVO<JgPageVo<List<BusinessCategoryEvaluation>>> listBusinessCategoryEvaluation(Long enterpriseId, BusinessCategoryEvaluationDto businessCategoryEvaluationDto) {
        PageHelper.startPage(businessCategoryEvaluationDto.getCurPage(), businessCategoryEvaluationDto.getMaxPage());
        QueryWrapper<BusinessCategoryEvaluation> queryWrapper = new QueryWrapper();
        queryWrapper.orderByDesc("create_time");
        if (businessCategoryEvaluationDto.getBusinessCategoryId() != null) {
            queryWrapper.eq("business_category_id", businessCategoryEvaluationDto.getBusinessCategoryId());
        }
        if (StringUtils.isNotBlank(businessCategoryEvaluationDto.getItemName())) {
            queryWrapper.like("item_name", businessCategoryEvaluationDto.getItemName());
        }
        List<BusinessCategoryEvaluation> businessCategoryEvaluations = businessCategoryEvaluationMapper.selectList(queryWrapper);
        businessCategoryEvaluations.forEach(businessCategoryEvaluation -> {
            BusinessCategory businessCategory = businessCategoryMapper.selectById(businessCategoryEvaluation.getBusinessCategoryId());
            if (businessCategory != null) {
                businessCategoryEvaluation.setBusinessName(businessCategory.getBusinessName());
            }
            Integer topicNum = businessCategoryTopicMapper.selectCount(new LambdaQueryWrapper<BusinessCategoryTopic>()
                    .eq(BusinessCategoryTopic::getCommonId, businessCategoryEvaluation.getId()));
            businessCategoryEvaluation.setTopicNum(topicNum);
//            Integer testNum = businessCategoryEvaluationHistoryMapper.selectCount(new LambdaQueryWrapper<BusinessCategoryEvaluationHistory>()
//                    .eq(BusinessCategoryEvaluationHistory::getBusinessCategoryEvaluationId, businessCategoryEvaluation.getId()));
            if (enterpriseId == null) {
                Integer testNum = wxUserBusinessCategoryGroupMapper.selectCount(new LambdaQueryWrapper<WxUserBusinessCategoryGroup>()
                        .eq(WxUserBusinessCategoryGroup::getCommonId, businessCategoryEvaluation.getId())
                        .eq(WxUserBusinessCategoryGroup::getType, 2)
                        .eq(WxUserBusinessCategoryGroup::getExamStatus, 0));
                businessCategoryEvaluation.setTestNum(testNum);
            } else {
                Integer testNum = wxUserBusinessCategoryGroupMapper.selectCount(new LambdaQueryWrapper<WxUserBusinessCategoryGroup>()
                        .eq(WxUserBusinessCategoryGroup::getCommonId, businessCategoryEvaluation.getId())
                        .eq(WxUserBusinessCategoryGroup::getType, 2)
                        .eq(WxUserBusinessCategoryGroup::getEnterpriseId, enterpriseId)
                        .eq(WxUserBusinessCategoryGroup::getExamStatus, 0));
                businessCategoryEvaluation.setTestNum(testNum);
            }
        });
        return new ReturnVO("工厂体检/星级认证列表查询成功", new JgPageVo<>(new PageInfo(businessCategoryEvaluations)));

    }


    @Autowired
    private BusinessCategoryEvaluationHistoryMapper businessCategoryEvaluationHistoryMapper;


    @Autowired
    private IEnterpriseOrganizationApiFeign enterpriseOrganizationApiFeign;

    @Override
    public ReturnVO<JgPageVo<List<BusinessCategoryEvaluationHistory>>> listBusinessCategoryEvaluationHistory(BusinessCategoryEvaluationHistoryDto businessCategoryEvaluationHistoryDto) {
        PageHelper.startPage(businessCategoryEvaluationHistoryDto.getCurPage(), businessCategoryEvaluationHistoryDto.getMaxPage());
        QueryWrapper<BusinessCategoryEvaluationHistory> queryWrapper = new QueryWrapper();
        queryWrapper.orderByDesc("create_time");
        if (businessCategoryEvaluationHistoryDto.getStartTimeStart() != null && businessCategoryEvaluationHistoryDto.getStartTimeEnd() != null) {
            queryWrapper.between("create_time", businessCategoryEvaluationHistoryDto.getStartTimeStart().toString(), businessCategoryEvaluationHistoryDto.getStartTimeEnd().toLocalDate().toString()+" 23:59");
        }
        if (businessCategoryEvaluationHistoryDto.getBusinessCategoryId() != null) {
            queryWrapper.eq("business_category_id", businessCategoryEvaluationHistoryDto.getBusinessCategoryId());
        }
        if (StringUtils.isNotBlank(businessCategoryEvaluationHistoryDto.getProjectName())) {
            queryWrapper.like("project_name", businessCategoryEvaluationHistoryDto.getProjectName() + "%");
        }
        if (StringUtils.isNotBlank(businessCategoryEvaluationHistoryDto.getWxUserRealName())) {
            queryWrapper.like("wx_user_real_name", businessCategoryEvaluationHistoryDto.getWxUserRealName() + "%");
        }
        if (businessCategoryEvaluationHistoryDto.getWxUserId() != null) {
            queryWrapper.eq("wx_user_id", businessCategoryEvaluationHistoryDto.getWxUserId());
        }
        if (businessCategoryEvaluationHistoryDto.getBusinessCategoryEvaluationId() != null) {
            queryWrapper.eq("business_category_evaluation_id", businessCategoryEvaluationHistoryDto.getBusinessCategoryEvaluationId());
        }
        if (businessCategoryEvaluationHistoryDto.getEnterpriseId() != null) {
            queryWrapper.eq("enterprise_id", businessCategoryEvaluationHistoryDto.getEnterpriseId());
        }
        if (businessCategoryEvaluationHistoryDto.getEnterpriseOrganizationId() != null) {
            queryWrapper.eq("enterprise_organization_id", businessCategoryEvaluationHistoryDto.getEnterpriseOrganizationId());
        }
        List<BusinessCategoryEvaluationHistory> businessCategoryEvaluationHistories = businessCategoryEvaluationHistoryMapper.selectList(queryWrapper);
        for (BusinessCategoryEvaluationHistory businessCategoryEvaluationHistory : businessCategoryEvaluationHistories) {
            if (businessCategoryEvaluationHistory.getEnterpriseOrganizationId() != null) {
                ReturnVO<String> stringReturnVO = enterpriseOrganizationApiFeign.selectOrganizationById(businessCategoryEvaluationHistory.getEnterpriseOrganizationId());
                JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
                businessCategoryEvaluationHistory.setOrganizationName(jsonObject.getString("organizationName"));
            }
        }
        return new ReturnVO("测评记录查询成功", new JgPageVo<>(new PageInfo(businessCategoryEvaluationHistories)));
    }


    @Autowired
    private TopicHistoryMapper topicHistoryMapper;

    @Override
    public ReturnVO<JgPageVo<List<TopicHistory>>> listTopicHistory(TopicHistoryDto topicHistoryDto) {
        PageHelper.startPage(topicHistoryDto.getCurPage(), topicHistoryDto.getMaxPage());
        QueryWrapper<TopicHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("business_type", topicHistoryDto.getBusinessType());
        if (topicHistoryDto.getCommonId() == null) {
            throw new SecurityException("请传入commonId");
        }
        queryWrapper.eq("common_id", topicHistoryDto.getCommonId());
        if (StringUtils.isNotBlank(topicHistoryDto.getTopicName())) {
            queryWrapper.like("topic_name", topicHistoryDto.getTopicName() + "%");
        }
        List<TopicHistory> topicHistories = topicHistoryMapper.selectList(queryWrapper);

        return new ReturnVO("测评记录查询成功", new JgPageVo<>(new PageInfo(topicHistories)));
    }

    @Autowired
    private BusinessCategoryTopicMapper businessCategoryTopicMapper;

    @Autowired
    private BusinessCategoryRuleMapper businessCategoryRuleMapper;

    @Override
    public ReturnVO<BusinessCategoryEvaluation> selectBusinessCategoryEvaluationDetailById(Long enterpriseId,Long wxUserId, Long businessCategoryEvaluationId) {
        BusinessCategoryEvaluation businessCategoryEvaluation = businessCategoryEvaluationMapper.selectById(businessCategoryEvaluationId);
        //题目数量
        Integer topicNum = businessCategoryTopicMapper.selectCount(new LambdaQueryWrapper<BusinessCategoryTopic>()
                .eq(BusinessCategoryTopic::getCommonId, businessCategoryEvaluationId)
                .eq(BusinessCategoryTopic::getType, 2));
        businessCategoryEvaluation.setTopicNum(topicNum);
        //是否测评过
        Integer isTest = businessCategoryEvaluationHistoryMapper.selectCount(new LambdaQueryWrapper<BusinessCategoryEvaluationHistory>()
                .eq(BusinessCategoryEvaluationHistory::getBusinessCategoryEvaluationId, businessCategoryEvaluationId)
                .eq(BusinessCategoryEvaluationHistory::getWxUserId, wxUserId));
        if (isTest > 0) {
            businessCategoryEvaluation.setIsTest(1);
        }
        Integer testNum = wxUserBusinessCategoryGroupMapper.selectCount(new LambdaQueryWrapper<WxUserBusinessCategoryGroup>()
                .eq(WxUserBusinessCategoryGroup::getCommonId, businessCategoryEvaluation.getId())
                .eq(WxUserBusinessCategoryGroup::getType, 2)
                .eq(WxUserBusinessCategoryGroup::getEnterpriseId, enterpriseId)
                .eq(WxUserBusinessCategoryGroup::getExamStatus, 0));
        businessCategoryEvaluation.setTestNum(testNum);
        return new ReturnVO("测评记录查询成功", businessCategoryEvaluation);
    }

    @Autowired
    private IEnterpriseApiFeign enterpriseApiFeign;

    @Autowired
    private BusinessCategoryRuleHistoryMapper businessCategoryRuleHistoryMapper;

    @Autowired
    private BusinessCategoryRuleGroupMapper businessCategoryRuleGroupMapper;

    @Override
    public ReturnVO<EvaluationDataDto> selectByEvaluationDataDto(Long enterpriseId) {
        EvaluationDataDto evaluationDataDto = new EvaluationDataDto();
        //参与测评名称
        List<String> evaluationJoinPersonDtosEvaluationName = Lists.newArrayList();
        //累计参与测评人数
        List<Integer> evaluationJoinPersonDtosEvaluationPersonNum = Lists.newArrayList();
        //累计参与测评次数
        List<Integer> evaluationJoinNumDtosEvaluationNum = Lists.newArrayList();
        //累计参与人数
        Integer allEvaluationPersonNum = 0;
        //查询该行业所有星级认证
        ReturnVO<String> stringReturnVO = enterpriseApiFeign.selectEnterpriseById(enterpriseId);
        JSONObject returnJsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
        List<BusinessCategoryRule> businessCategoryRules = businessCategoryRuleMapper.selectList(new LambdaQueryWrapper<BusinessCategoryRule>()
                .eq(BusinessCategoryRule::getBusinessCategoryId, returnJsonObject.getLong("businessCategoryId"))
                .eq(BusinessCategoryRule::getType, 1));
        for (BusinessCategoryRule businessCategoryRule : businessCategoryRules) {
            evaluationJoinPersonDtosEvaluationName.add(businessCategoryRule.getRuleName());
            //参与测评人数
            Integer personNum = businessCategoryRuleGroupMapper.selectBusinessCategoryRuleGroupPerson(businessCategoryRule.getId(), enterpriseId, 1);
            evaluationJoinPersonDtosEvaluationPersonNum.add(personNum);
            allEvaluationPersonNum = allEvaluationPersonNum + personNum;
            //参与测评次数
            Integer joinCount = businessCategoryRuleHistoryMapper.selectCount(new LambdaQueryWrapper<BusinessCategoryRuleHistory>()
                    .eq(BusinessCategoryRuleHistory::getEnterpriseId, enterpriseId)
                    .eq(BusinessCategoryRuleHistory::getBusinessCategoryRuleId, businessCategoryRule.getId()));
            evaluationJoinNumDtosEvaluationNum.add(joinCount);
        }
        //查询所有能力测评
        List<BusinessCategoryEvaluation> businessCategoryEvaluations = businessCategoryEvaluationMapper.selectList(new LambdaQueryWrapper<BusinessCategoryEvaluation>()
                .eq(BusinessCategoryEvaluation::getBusinessCategoryId, returnJsonObject.getLong("businessCategoryId")));
        for (BusinessCategoryEvaluation businessCategoryEvaluation : businessCategoryEvaluations) {
            evaluationJoinPersonDtosEvaluationName.add(businessCategoryEvaluation.getItemName());
            //参与测评人数
            Integer personNum = businessCategoryEvaluationHistoryMapper.selectBusinessCategoryEvaluationHistoryPerson(businessCategoryEvaluation.getId(), enterpriseId);
            evaluationJoinPersonDtosEvaluationPersonNum.add(personNum);
            allEvaluationPersonNum = allEvaluationPersonNum + personNum;
            //参与测评次数
            Integer joinCount = businessCategoryEvaluationHistoryMapper.selectCount(new LambdaQueryWrapper<BusinessCategoryEvaluationHistory>()
                    .eq(BusinessCategoryEvaluationHistory::getEnterpriseId, enterpriseId)
                    .eq(BusinessCategoryEvaluationHistory::getBusinessCategoryEvaluationId, businessCategoryEvaluation.getId()));
            evaluationJoinNumDtosEvaluationNum.add(joinCount);
        }
        //累计参与测评次数
        Integer allEvaluationNum = businessCategoryRules.size() + businessCategoryEvaluations.size();
        evaluationDataDto.setAllEvaluationNum(allEvaluationNum);
        evaluationDataDto.setAllEvaluationPersonNum(allEvaluationPersonNum);
        evaluationDataDto.setEvaluationJoinPersonDtosEvaluationName(evaluationJoinPersonDtosEvaluationName);
        evaluationDataDto.setEvaluationJoinPersonDtosEvaluationPersonNum(evaluationJoinPersonDtosEvaluationPersonNum);
        evaluationDataDto.setEvaluationJoinNumDtosEvaluationNum(evaluationJoinNumDtosEvaluationNum);
        return new ReturnVO<>("参与测试查询成功", evaluationDataDto);
    }

    @Autowired
    private WxUserBusinessCategoryGroupMapper wxUserBusinessCategoryGroupMapper;

    @Override
    public ReturnVO saveWxUserBusinessCategoryGroup(Long enterpriseId, WxUserBusinessCategoryEvaluationDto wxUserBusinessCategoryEvaluationDto) {
        BusinessCategoryEvaluation businessCategoryEvaluation = businessCategoryEvaluationMapper.selectById(wxUserBusinessCategoryEvaluationDto.getBusinessCategoryEvaluationId());
        Optional.ofNullable(businessCategoryEvaluation).orElseThrow(() -> new ServiceException("该能力测评不存在"));
        if (wxUserBusinessCategoryEvaluationDto.getWxUserIds() != null) {
            //先全部禁考
            List<WxUserBusinessCategoryGroup> wxUserBusinessCategoryGroups = wxUserBusinessCategoryGroupMapper.selectList(new LambdaQueryWrapper<WxUserBusinessCategoryGroup>()
                    .eq(WxUserBusinessCategoryGroup::getExamStatus, 0)
                    .eq(WxUserBusinessCategoryGroup::getType, 2)
                    .eq(WxUserBusinessCategoryGroup::getCommonId, wxUserBusinessCategoryEvaluationDto.getBusinessCategoryEvaluationId()));
            for (WxUserBusinessCategoryGroup wxUserBusinessCategoryGroup : wxUserBusinessCategoryGroups) {
                //禁考
                wxUserBusinessCategoryGroup.setExamStatus(1);
                wxUserBusinessCategoryGroupMapper.updateById(wxUserBusinessCategoryGroup);
            }
            //重新分配
            for (Long wxUserId : wxUserBusinessCategoryEvaluationDto.getWxUserIds()) {
                WxUserBusinessCategoryGroup wxUserBusinessCategoryGroup = wxUserBusinessCategoryGroupMapper.selectOne(new LambdaQueryWrapper<WxUserBusinessCategoryGroup>()
                        .eq(WxUserBusinessCategoryGroup::getCommonId, wxUserBusinessCategoryEvaluationDto.getBusinessCategoryEvaluationId())
                        .eq(WxUserBusinessCategoryGroup::getType, 2)
                        .eq(WxUserBusinessCategoryGroup::getExamStatus, 0)
                        .eq(WxUserBusinessCategoryGroup::getWxUserId, wxUserId));
                //如果不存在则添加上去
                if (wxUserBusinessCategoryGroup == null) {
                    WxUserBusinessCategoryGroup save = new WxUserBusinessCategoryGroup();
                    save.setCommonId(wxUserBusinessCategoryEvaluationDto.getBusinessCategoryEvaluationId());
                    save.setEnterpriseId(enterpriseId);
                    save.setType(2);
                    save.setWxUserId(wxUserId);
                    wxUserBusinessCategoryGroupMapper.insert(save);
                } else {
                    //如果存在则直接改为可考
                    wxUserBusinessCategoryGroup.setExamStatus(0);
                    wxUserBusinessCategoryGroupMapper.updateById(wxUserBusinessCategoryGroup);
                }
                //todo 小程序订阅
                SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
                systemMessageMqDto.setMessageDetail("您已被纳入" + businessCategoryEvaluation.getItemName() + "能力测评中,请及时完成测评");
                systemMessageMqDto.setMessageTitle("能力测评");
                systemMessageMqDto.setWxUserIds(wxUserBusinessCategoryEvaluationDto.getWxUserIds());
                evaluationProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
            }
        }
        return new ReturnVO("能力测评人员分配成功", businessCategoryEvaluation.getId());
    }

    @Autowired
    private EvaluationProducer evaluationProducer;


    @Autowired
    private IWxUserApiFeign wxUserApiFeign;

    @Override
    public ReturnVO<JgPageVo<List<WxUserBusinessCategoryGroup>>> selectWxUserBusinessCategoryEvaluationBind(Long enterpriseId, WxUserBusinessCategoryEvaluationBindDto wxUserBusinessCategoryEvaluationBindDto) {
        BusinessCategoryEvaluation businessCategoryEvaluation = businessCategoryEvaluationMapper.selectById(wxUserBusinessCategoryEvaluationBindDto.getBusinessCategoryEvaluationId());
        Optional.ofNullable(businessCategoryEvaluation).orElseThrow(() -> new ServiceException("该能力测评不存在"));
        PageHelper.startPage(wxUserBusinessCategoryEvaluationBindDto.getCurPage(), wxUserBusinessCategoryEvaluationBindDto.getMaxPage());
        List<WxUserBusinessCategoryGroup> wxUserBusinessCategoryGroups = wxUserBusinessCategoryGroupMapper.selectList(new LambdaQueryWrapper<WxUserBusinessCategoryGroup>()
                .eq(WxUserBusinessCategoryGroup::getCommonId, wxUserBusinessCategoryEvaluationBindDto.getBusinessCategoryEvaluationId())
                .eq(WxUserBusinessCategoryGroup::getExamStatus, 0)
                .eq(WxUserBusinessCategoryGroup::getType, 2)
                .eq(WxUserBusinessCategoryGroup::getEnterpriseId, enterpriseId));
        for (WxUserBusinessCategoryGroup wxUserBusinessCategoryGroup : wxUserBusinessCategoryGroups) {
            //查询用户信息
            ReturnVO<String> stringReturnVO = wxUserApiFeign.selectWxUserByWxUserId(wxUserBusinessCategoryGroup.getWxUserId());
            JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
            wxUserBusinessCategoryGroup.setNickname(jsonObject.getString("nickname"));
            wxUserBusinessCategoryGroup.setIcon(jsonObject.getString("icon"));
            wxUserBusinessCategoryGroup.setPhone(jsonObject.getString("phone"));
            wxUserBusinessCategoryGroup.setOrganizationName(jsonObject.getString("organizationName"));
            wxUserBusinessCategoryGroup.setIdentityName(jsonObject.getString("identityName"));
        }
        return new ReturnVO("绑定人员查询成功", new JgPageVo<>(new PageInfo(wxUserBusinessCategoryGroups)));
    }


}
